#include <iostream>
#include <string.h>     // 定义memset
#include <cassert>      // 定义assert
#include <memory>
#include <utility>

using std::cout;
using std::endl;
using std::ostream;
using std::unique_ptr;

class sso_string{
public:
    // 构造函数与析构函数
    sso_string();
    sso_string(const char* pstr);
    //~sso_string();
    ~sso_string();

    // 基础操作
    // sso_string(const char& rhs); // 类型写错了
    sso_string(const sso_string& rhs); // 类型写错了
    sso_string(sso_string&& rhs);
    sso_string &operator=(const sso_string& rhs);
    sso_string &operator=(sso_string&& rhs);
    friend ostream &operator<<(ostream &os, const sso_string& rhs);

    // 辅助函数
    const char* c_str() const;
    size_t size() const { return _size; }
    bool empty() const { return _size == 0; }

private:
    union Buffer{
        char* _pointer;
        char _array[16];
    };
    Buffer _buffer;
    int _size;
};

sso_string::sso_string()
    :_size(0){
        memset(_buffer._array, 0, sizeof(_buffer._array));
    }

sso_string::sso_string(const char *pstr)
    :_size(strlen(pstr)){
        if(_size <= 15){
            memset(_buffer._array, 0, sizeof(_buffer._array));
            strcpy(_buffer._array, pstr);
        }
        else{
            _buffer._pointer = new char[_size + 1]();    // 注意初始化，_size已经被赋值为strlen(pstr)
            strcpy(_buffer._pointer, pstr);
        }
    }

sso_string::sso_string(const sso_string &rhs)
    :_size(rhs._size){
        if(_size <= 15){
            memset(_buffer._array, 0, sizeof(_buffer._array));
            strcpy(_buffer._array, rhs._buffer._array);
        }
        else{
            _buffer._pointer = new char[_size + 1]();    // 注意初始化，_size已经被赋值为strlen(pstr)
            strcpy(_buffer._pointer, rhs._buffer._pointer);
        }
    }

sso_string::sso_string(sso_string&& rhs)
    :_size(rhs._size){
        if(_size <= 15){
            // 栈上不能窃取
            memcpy(_buffer._array, rhs._buffer._array, _size + 1);
//            rhs._size = 0;
        }
        else{
            // 堆上能窃取
            _buffer._pointer = rhs._buffer._pointer;    // 所有权转移
            rhs._buffer._pointer = nullptr;             // 置空原指针
//            rhs._size = 0;                              // 重置原对象状态
        }

        rhs._size = 0;
    }

sso_string::~sso_string(){
    if(_size > 15){
        if(_buffer._pointer){
            delete [] _buffer._pointer;
            _buffer._pointer = nullptr;
        }
    }
}

sso_string& sso_string::operator=(const sso_string& rhs){
    if(this != &rhs){
        // 处理被赋值的字符串
        if(_size <= 15){
            memset(_buffer._array, 0, sizeof(_buffer._array));
        }else{
            delete []_buffer._pointer;
        }

        // 赋值
        if(rhs._size <= 15){
            strcpy(_buffer._array, rhs._buffer._array);
        }else{
            _buffer._pointer = new char[rhs._size + 1]();
            strcpy(_buffer._pointer, rhs._buffer._pointer);
        }
        _size = rhs._size;
    }

    return *this;
    
}

sso_string& sso_string::operator=(sso_string&& rhs){
    if(this != &rhs){
        // 处理被赋值的字符串
        if(_size <= 15){
            memset(_buffer._array, 0, sizeof(_buffer._array));
        }else{
            delete []_buffer._pointer;
        }

        // 赋值
        if(rhs._size <= 15){
            strcpy(_buffer._array, rhs._buffer._array);
        }else{
            _buffer._pointer = rhs._buffer._pointer;
            rhs._buffer._pointer = nullptr;
        }
        _size = rhs._size;
        rhs._size = 0;
    }

    return *this;
}

const char* sso_string::c_str() const{
    if(_size <= 15){
        return _buffer._array; 
    }else{
        return _buffer._pointer;
    }
}

void test_constructor() {
    // 默认构造
    sso_string s1;
    assert(s1.empty());
    assert(s1.size() == 0);
    assert(strcmp(s1.c_str(), "") == 0);

    // 短字符串构造（SSO）
    sso_string s2("hello");
    assert(strcmp(s2.c_str(), "hello") == 0);
    assert(s2.size() == 5);

    // 长字符串构造（堆分配）
    sso_string s3("this_is_a_very_long_string_exceeding_15_chars");
    assert(s3.size() > 15);
    assert(strcmp(s3.c_str(), "this_is_a_very_long_string_exceeding_15_chars") == 0);
}

void test_copy_semantics() {
    // 短字符串拷贝
    sso_string s1("short");
    sso_string s2 = s1;
    assert(strcmp(s2.c_str(), "short") == 0);
    assert(s1.c_str() != s2.c_str());  // 深拷贝验证

    // 长字符串拷贝
    sso_string s3("long_string_needs_heap");
    sso_string s4 = s3;
    assert(strcmp(s4.c_str(), s3.c_str()) == 0);
    assert(s4.c_str() != s3.c_str());  // 深拷贝验证

    // 自赋值
    s4 = s4;
    assert(strcmp(s4.c_str(), s3.c_str()) == 0);
}

void test_move_semantics() {
    // 短字符串移动
    sso_string s1("short");
    const char* s1_data = s1.c_str();
    sso_string s2 = std::move(s1);
    assert(strcmp(s2.c_str(), "short") == 0);
    assert(s1.empty());  // 源对象应被置空

    // 长字符串移动
    sso_string s3("very_long_string_for_heap");
    const char* s3_data = s3.c_str();
    sso_string s4 = std::move(s3);
    assert(strcmp(s4.c_str(), s3_data) == 0);  // 指针应相同
    assert(s3.empty());
}

void test_assignment() {
    // 拷贝赋值
    sso_string s1("src");
    sso_string s2;
    s2 = s1;
    assert(strcmp(s2.c_str(), "src") == 0);

    // 移动赋值
    sso_string s3("movable");
    const char* s3_data = s3.c_str();
    sso_string s4;
    s4 = std::move(s3);
    assert(strcmp(s4.c_str(), s3_data) == 0);
    assert(s3.empty());
}

void test_edge_cases() {
    // 空字符串
    sso_string s1("");
    assert(s1.empty());

    // 边界长度测试（15和16字符）
    sso_string s2("exactly_15_char");  // SSO模式
    assert(s2.size() == 15);

    sso_string s3("exactly_16_chars");  // 堆模式
    assert(s3.size() == 16);

    // 内存泄漏检测（需结合valgrind等工具）
    sso_string* p = new sso_string("dynamic");
    delete p;
}

void test_combined_operations() {
    sso_string s1("start");
    sso_string s2 = s1;          // 拷贝构造
    sso_string s3 = std::move(s1); // 移动构造
    s2 = s3;                     // 拷贝赋值
    s3 = sso_string("temp");     // 移动赋值
    assert(strcmp(s2.c_str(), "start") == 0);
}

int main() {
    test_constructor();
    test_copy_semantics();
    test_move_semantics();
    test_assignment();
    test_edge_cases();
    test_combined_operations();

    std::cout << "All tests passed!" << std::endl;
    return 0;
}
